package com.renfei.multimediatask.ui.task6;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.util.Log;

import com.renfei.multimediatask.R;
import com.renfei.multimediatask.base.BaseActivity;
import com.renfei.multimediatask.util.OpenGlUtils;
import com.renfei.multimediatask.util.ScreenUtils;

import java.lang.ref.WeakReference;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import butterknife.BindView;

public class OpenGLDrawImageFboActivity extends BaseActivity {


    @BindView(R.id.glSurfaceView)
    GLSurfaceView glSurfaceView;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_open_g_l_draw_image;
    }

    @Override
    protected void initListener() {
        glSurfaceView.setEGLContextClientVersion(2);
        glSurfaceView.setRenderer(new DrawImageRender(new WeakReference<>(this)));
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    static class DrawImageRender implements GLSurfaceView.Renderer {
        private WeakReference<OpenGLDrawImageFboActivity> weakReference;


        private float[] vertexData = {
                -1.0f, -1.0f,
                1.0f, -1.0f,
                -1.0f, 1.0f,
                1.0f, 1.0f
        };


        /**
         * 设置和设备同样 坐标系时， 图片正常显示
         */
        private float[] textureData = {
                0.0f, 1.0f,
                1.0f, 1.0f,
                0.0f, 0.0f,
                1.0f, 0.0f
        };

        private FloatBuffer vertexBuffer;
        private FloatBuffer textureBuffer;

        private int program;

        private int v_Position; //attribute vec4
        private int f_Position; //attribute vec2
        private int sTexture;   //uniform sampler2D ;

        private int imageTextureID;

        //在这里测试下FBO

        //先将图片纹理渲染到FBO上 ， 然后再将将fbo的内容绘制到屏幕上

        private  int fboID;
        private int fboTextureID;


        private int fboWidth;
        private int fboHeight;

        public DrawImageRender(WeakReference<OpenGLDrawImageFboActivity> weakReference) {
            this.weakReference = weakReference;

            vertexBuffer = OpenGlUtils.createFloatBuffer(vertexData);
            textureBuffer = OpenGlUtils.createFloatBuffer(textureData);

            //vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * OpenGlUtils.SIZEOF_FLOAT)
            //        .order(ByteOrder.nativeOrder())
            //        .asFloatBuffer();
            //vertexBuffer.put(vertexData).position(0);
            //textureBuffer = ByteBuffer.allocateDirect(textureData.length * OpenGlUtils.SIZEOF_FLOAT)
            //        .order(ByteOrder.nativeOrder())
            //        .asFloatBuffer();
            //textureBuffer.put(textureData).position(0);


        }

        @Override
        public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
            String vertexShaderSource = OpenGlUtils.readShaderFromRawResource(weakReference.get(), R.raw.draw_image_vertex_shader);
            String textureShaderSource = OpenGlUtils.readShaderFromRawResource(weakReference.get(), R.raw.draw_image_fragment_shader);

            int vertexShaderId = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
            OpenGlUtils.checkGlError("glCreateShader type=" + GLES20.GL_VERTEX_SHADER);
            GLES20.glShaderSource(vertexShaderId, vertexShaderSource);
            GLES20.glCompileShader(vertexShaderId);


            int fragmentShaderId = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
            OpenGlUtils.checkGlError("glCreateShader type=" + GLES20.GL_VERTEX_SHADER);
            GLES20.glShaderSource(fragmentShaderId, textureShaderSource);
            GLES20.glCompileShader(fragmentShaderId);


            program = GLES20.glCreateProgram();
            GLES20.glAttachShader(program, vertexShaderId);
            GLES20.glAttachShader(program, fragmentShaderId);
            GLES20.glLinkProgram(program);

//            program = OpenGlUtils.createProgram(vertexShaderSource, textureShaderSource);


            v_Position = GLES20.glGetAttribLocation(program, "v_Position");
            f_Position = GLES20.glGetAttribLocation(program, "f_Position");
            sTexture = GLES20.glGetUniformLocation(program, "sTexture");



        }



        @Override
        public void onSurfaceChanged(GL10 gl10, int width, int height) {
            GLES20.glViewport(0, 0, width, height);

            this.fboWidth=width;
            this.fboHeight=height;

            userFbo();
            createImageId();
        }

        @Override
        public void onDrawFrame(GL10 gl10) {
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
            GLES20.glClearColor(0.1f, 0.4f, 0.7f, 1.0f);


            //绘制到FBO
            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,fboID);
                GLES20.glUseProgram(program);

                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, imageTextureID);

                GLES20.glEnableVertexAttribArray(v_Position);
                GLES20.glVertexAttribPointer(v_Position, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer);
                GLES20.glEnableVertexAttribArray(f_Position);
                GLES20.glVertexAttribPointer(f_Position, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);

                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,0);


            //将fbo内容绘制到屏幕上


            GLES20.glUseProgram(program);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,fboTextureID);
                GLES20.glEnableVertexAttribArray(v_Position);
                GLES20.glVertexAttribPointer(v_Position, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer);
                GLES20.glEnableVertexAttribArray(f_Position);
                GLES20.glVertexAttribPointer(f_Position, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);

                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);
        }


        private void userFbo() {
            int[] fboArr=new int[1];
            GLES20.glGenFramebuffers(1,fboArr,0);
            fboID=fboArr[0];



            int[] textures = new int[1];
            GLES20.glGenTextures(1, textures, 0);
            fboTextureID = textures[0];
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboTextureID);

            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,fboID);






            GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,
                    fboWidth,
                    fboHeight,//需要离屏渲染的宽高
                    0,
                    GLES20.GL_RGBA,
                    GLES20.GL_UNSIGNED_BYTE,//
                    null//像素数据
            );
            GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
                    GLES20.GL_COLOR_ATTACHMENT0,
                    GLES20.GL_TEXTURE_2D,
                    fboTextureID,0
            );
            if (GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER)!=GLES20.GL_FRAMEBUFFER_COMPLETE){
                Log.e(BaseActivity.PROJECT_TAG,"FBO ERROR");
            }

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,0);
        }

        private void createImageId() {
            int[] textureArr=new int[1];
            GLES20.glGenTextures(1,textureArr,0);
            imageTextureID=textureArr[0];
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureArr[0]);

            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

            Bitmap bitmap = BitmapFactory.decodeResource(weakReference.get().getResources(), R.drawable.androids);
            //设置图片
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
            bitmap.recycle();
            bitmap = null;

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);
        }

    }
}
